package com.wang.auto;

import com.wang.conf.AppData;
import com.wang.packpojo.ConMsg;

import com.wang.packpojo.DebugConMsg;
import com.wang.pojo.DevControlFun;
import com.wang.pojo.DevLog;
import com.wang.pojo.DevMControl;
import com.wang.pojo.Device;
import com.wang.service.*;
import com.wang.socket.OutBoundHandler;
import com.wang.socket.SocketMap;
import com.wang.util.*;
import com.wang.webSocket.WebSocketMap;
import io.netty.channel.ChannelHandlerContext;
import lombok.SneakyThrows;


import java.text.ParseException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class AutoTask {

    //socket 心跳包时间
    public static final long autoHeartBeatTime = 1000 * 20;

    public static final long autoClearNotRegConnectClientTime = 1000 * 30;
    public static final long autoClearTestClientTime = 1000 * 30;

    public static final long spaceTime = 1000 * 60 * 3+10000 ;

    public static final long checkControlTime = 1000 *60* 60 ;

    /*
    检测心跳包机制
      1、当前时间-接收时间(接收心跳包时间) > 2分钟
         接收次数 = 0
      2、设备初始化的时间 默认接收时间是当前时间
      3、每隔1分钟检测一次
     */





    public void init() {

        Timer timer1 = new Timer();
        timer1.schedule(new TimerTask() {
            @SneakyThrows
            @Override
            public void run() {

                autoCheckClient();
            }
        }, new Date(), autoHeartBeatTime);


        Timer timer3 = new Timer();

        timer3.schedule(new TimerTask() {
            @Override
            public void run() {
                autoClearNotRegConnectClient();
            }
        }, new Date(), autoClearNotRegConnectClientTime);


        Timer timer4 = new Timer();
        timer4.schedule(new TimerTask() {
            @Override
            public void run() {
                autoClearTestClient();
            }
        }, new Date(), autoClearTestClientTime);

        Timer timer5 = new Timer();
        timer5.schedule(new TimerTask() {
            @Override
            public void run() {
                 autoCheckDevControlFunStatus();
            }
        }, new Date(), checkControlTime);

    }

    //检查设备心跳包
    public void autoCheckClient() throws ParseException {

        //获取modbus客户端连接列表
        if (SocketMap.mRegPassDeviceMap != null) {


            for (Map.Entry<String, ConMsg> entry : SocketMap.mRegPassDeviceMap.entrySet()) {

                //检测当前时间-设备接收心跳时间是否大于2分钟
                long currentTime = new Date().getTime();
                long receiveTime = entry.getValue().getConHeart().getReceiveTime().getTime();
                if (currentTime - receiveTime > spaceTime) {
                    ConMsg conMsg = entry.getValue();
                    PrintUtil.print("设备连接超时：" + conMsg.getDevice().getDevGId());
                    //设置设备离线
                    Device device = conMsg.getDevice();
                    DevStatusUtil.handerOfflineEvent(device.getDevId());

                    SocketMap.mRegPassDeviceMap.remove(entry.getKey());
                    //销毁通道
                    conMsg.getCtx().close();

                    //存储设备运行日志
                    DevLog devLog = new DevLog();
                    devLog.setDevId(device.getDevId().toString());
                    devLog.setDevLogTypeCode(AppData.devRunLogCode);
                    devLog.setDevEventTypeCode(AppData.devOffLineCode);
                    String msg = "设备离线";
                    devLog.setDevLogContent(msg);
                    devLog.setCreateTime(DateUtil.getStrDate());

                    devLog.setOperateUser("system");
                    devLog.setIsRead(1);
                    //存储
                    DevLogService devLogService = SpringUtil.getBean("devLogServiceImpl", DevLogServiceImpl.class);
                    devLogService.addDevLog(devLog);
                    //存储设备异常日志
                    devLog.setDevLogTypeCode(AppData.devExceptionLogCode);
                    devLogService.addDevLog(devLog);

                }

            }
        }
        //获取json客户端连接列表
        if (SocketMap.jRegPassDeviceMap != null) {


            for (Map.Entry<String, ConMsg> entry : SocketMap.jRegPassDeviceMap.entrySet()) {

                //检测当前时间-设备接收心跳时间是否大于2分钟
                long currentTime = new Date().getTime();
                long receiveTime = entry.getValue().getConHeart().getReceiveTime().getTime();
                if (currentTime - receiveTime > spaceTime) {
                    ConMsg conMsg = entry.getValue();
                    PrintUtil.print("设备连接超时：" + conMsg.getDevice().getDevGId());
                    PrintUtil.print("当前时间："+currentTime+"心跳包更新时间："+receiveTime);

                    //设置设备离线
                    Device device = conMsg.getDevice();
                    DevStatusUtil.handerOfflineEvent(device.getDevId());


                    SocketMap.jRegPassDeviceMap.remove(entry.getKey());
                    //销毁通道
                    conMsg.getCtx().close();


                    //存储日志
                    DevLog devLog = new DevLog();
                    devLog.setDevId(device.getDevId().toString());
                    devLog.setDevLogTypeCode(AppData.devRunLogCode);
                    devLog.setDevEventTypeCode(AppData.devOffLineCode);
                    String msg = "设备离线";
                    devLog.setDevLogContent(msg);
                    devLog.setCreateTime(DateUtil.getStrDate());

                    devLog.setOperateUser("system");
                    devLog.setIsRead(1);

                    //存储
                    DevLogService devLogService = SpringUtil.getBean("devLogServiceImpl", DevLogServiceImpl.class);
                    devLogService.addDevLog(devLog);

                    //存储设备异常日志
                    devLog.setDevLogTypeCode(AppData.devExceptionLogCode);
                    devLogService.addDevLog(devLog);


                }

            }
        }
        if (SocketMap.c2RegPassDeviceMap != null) {


            for (Map.Entry<String, ConMsg> entry : SocketMap.c2RegPassDeviceMap.entrySet()) {

                //检测当前时间-设备接收心跳时间是否大于2分钟
                long currentTime = new Date().getTime();
                long receiveTime = entry.getValue().getConHeart().getReceiveTime().getTime();
                if (currentTime - receiveTime > spaceTime) {
                    ConMsg conMsg = entry.getValue();
                    PrintUtil.print("设备连接超时：" + conMsg.getDevice().getDevGId());
                    PrintUtil.print("当前时间："+currentTime+"心跳包更新时间："+receiveTime);

                    //设置设备离线
                    Device device = conMsg.getDevice();
                    DevStatusUtil.handerOfflineEvent(device.getDevId());


                    SocketMap.c2RegPassDeviceMap.remove(entry.getKey());
                    //销毁通道
                    conMsg.getCtx().close();


                    //存储日志
                    DevLog devLog = new DevLog();
                    devLog.setDevId(device.getDevId().toString());
                    devLog.setDevLogTypeCode(AppData.devRunLogCode);
                    devLog.setDevEventTypeCode(AppData.devOffLineCode);
                    String msg = "设备离线";
                    devLog.setDevLogContent(msg);
                    devLog.setCreateTime(DateUtil.getStrDate());

                    devLog.setOperateUser("system");
                    devLog.setIsRead(1);

                    //存储
                    DevLogService devLogService = SpringUtil.getBean("devLogServiceImpl", DevLogServiceImpl.class);
                    devLogService.addDevLog(devLog);

                    //存储设备异常日志
                    devLog.setDevLogTypeCode(AppData.devExceptionLogCode);
                    devLogService.addDevLog(devLog);


                }

            }
        }

    }


    public void autoClearNotRegConnectClient() {
        if (SocketMap.notRegDeviceMap != null && !SocketMap.notRegDeviceMap.isEmpty()) {

            for (Map.Entry<String, ConMsg> entry : SocketMap.notRegDeviceMap.entrySet()) {

                //获取当前时间
                long currentTime = new Date().getTime();
                long connectTime = entry.getValue().getConnectTime();
                long date = 1000 * 20;
                if (currentTime - connectTime > date) {
                    ChannelHandlerContext ctx = entry.getValue().getCtx();
                    ctx.close();
                    SocketMap.notRegDeviceMap.remove(entry.getKey());
                    PrintUtil.print("清除了无效连接3：" + entry.getKey());
                }

            }

        }
    }

    //检测钉钉 微信 web  调试心跳包
    public void autoClearTestClient() {
        //钉钉心跳包
        if (WebSocketMap.clientDDCtxMap != null && !WebSocketMap.clientDDCtxMap.isEmpty()) {

            for (Map.Entry<String, DebugConMsg> entry : WebSocketMap.clientDDCtxMap.entrySet()) {

                //获取当前时间
                long currentTime = new Date().getTime();
                long receiveTime = entry.getValue().getWebSocketConMsg().getConHeart().getReceiveTime().getTime();

                if (currentTime - receiveTime > spaceTime) {
                    ChannelHandlerContext ctx = entry.getValue().getWebSocketConMsg().getCtx();
                    ctx.close();
                    WebSocketMap.clientDDCtxMap.remove(entry.getKey());
                    PrintUtil.print("清除了无效连接3：" + entry.getKey());
                }

            }


        }
        //微信心跳包
        if (WebSocketMap.clientWXCtxMap != null && !WebSocketMap.clientWXCtxMap.isEmpty()) {

            for (Map.Entry<String, DebugConMsg> entry : WebSocketMap.clientWXCtxMap.entrySet()) {

                //获取当前时间
                long currentTime = new Date().getTime();
                long receiveTime = entry.getValue().getWebSocketConMsg().getConHeart().getReceiveTime().getTime();

                if (currentTime - receiveTime > spaceTime) {
                    ChannelHandlerContext ctx = entry.getValue().getWebSocketConMsg().getCtx();
                    ctx.close();
                    WebSocketMap.clientWXCtxMap.remove(entry.getKey());
                    PrintUtil.print("清除了无效连接4：" + entry.getKey());
                }

            }


        }
        //WEB心跳包
        if (WebSocketMap.clientWEBCtxMap != null && !WebSocketMap.clientWEBCtxMap.isEmpty()) {

            for (Map.Entry<String, DebugConMsg> entry : WebSocketMap.clientWEBCtxMap.entrySet()) {

                //获取当前时间
                long currentTime = new Date().getTime();
                long receiveTime = entry.getValue().getWebSocketConMsg().getConHeart().getReceiveTime().getTime();

                if (currentTime - receiveTime > spaceTime) {
                    ChannelHandlerContext ctx = entry.getValue().getWebSocketConMsg().getCtx();
                    ctx.close();
                    WebSocketMap.clientWEBCtxMap.remove(entry.getKey());
                    PrintUtil.print("清除了无效连接5：" + entry.getKey());
                }

            }


        }


    }


    //检测设备功能能控制开启状态
    public void autoCheckDevControlFunStatus(){

        //从控制功能中获取列表
        DevControlFunService devControlFunService = SpringUtil.getBean("devControlFunServiceImpl",DevControlFunServiceImpl.class);
        List<DevControlFun> devControlFunList = devControlFunService.list();
        devControlFunList.forEach(devControlFun -> {

            //发送查询
            DevMControlService devMControlService = SpringUtil.getBean("devMControlServiceImpl",DevMControlServiceImpl.class);
            List<DevMControl> devMControlList = devMControlService.selectDevControlByFunId(devControlFun.getFunId());



            devMControlList.forEach(devMControl -> {

                if(devMControl.getMakeProperty().equals("read")){
                    DeviceService deviceService = SpringUtil.getBean("deviceServiceImpl",DeviceServiceImpl.class);
                    Device device = deviceService.selectDeviceByDevId(devControlFun.getDevId());
                    if(device!=null) {
                        String devGId = device.getDevGId();

                        ConMsg conMsg = null;
                        for (Map.Entry<String, ConMsg> entry : SocketMap.mRegPassDeviceMap.entrySet()) {
                            if (entry.getValue().getDevice().getDevGId().equals(devGId)) {
                                conMsg = entry.getValue();
                                break;
                            }
                        }
                        if (conMsg != null) {
                            byte[] commandByte = ModBusUtil.HexString2Bytes(devMControl.getControlData());

                            OutBoundHandler.outData(conMsg.getCtx(), commandByte);
                            PrintUtil.print("服务端发送查询指令-->设备编码：" + devGId + "：" + devMControl.getControlData());

                            if (AppData.returnMap.containsKey(devGId)) {
                                AppData.returnMap.get(devGId).put(devMControl.getControlId().toString(), null);
                            } else {
                                Map<String, Object> map = new HashMap<>();
                                map.put(devMControl.getControlId().toString(), null);
                                AppData.returnMap.put(devGId, map);

                            }

                        }
                    }

                }

                //休眠5秒 防止指令同时发送
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            });

        });


    }
}

